//
//  NSObject+Swizzling.m
//  WProjectForNative
//
//  Created by HuangZhen on 16/9/11.
//  Copyright © 2016年 HuangZhen. All rights reserved.
//

#import "NSObject+Swizzling.h"
#import <objc/runtime.h>
@implementation NSObject (Swizzling)
+ (void)swizzlingWithOriginalSEL:(SEL)originalSEL
                          newSEL:(SEL)newSEL
                      defaultSEL:(SEL)defaultSEL
                 targetClassName:(NSString *)targetClassName
{
    Class selfClass = [self class];
    Class targetClass;
    if (targetClassName.length > 0) {
        targetClass = objc_getClass([targetClassName UTF8String]);
    }else {
        targetClass = selfClass;
    }
    NSAssert(targetClass, @"TargetClass NotFound");
    if (defaultSEL) {
        class_addMethod(targetClass, newSEL, class_getMethodImplementation(selfClass, newSEL),nil);
        class_addMethod(targetClass, originalSEL, class_getMethodImplementation(selfClass, defaultSEL),nil);
        Method oldMethod = class_getInstanceMethod(targetClass, originalSEL);
        if (!oldMethod) {
            oldMethod = class_getClassMethod(targetClass, originalSEL);
        }
        Method newMethod = class_getInstanceMethod(targetClass, newSEL);
        if (!newMethod) {
            newMethod = class_getClassMethod(targetClass, newSEL);
        }
        method_exchangeImplementations(oldMethod, newMethod);
    }else {
        Method originMethod = class_getInstanceMethod(targetClass,originalSEL);
        if (!originMethod) {
            originMethod = class_getClassMethod(targetClass, originalSEL);
        }
        Method newMethod = class_getInstanceMethod(selfClass, newSEL);
        if (!newMethod) {
            newMethod = class_getClassMethod(selfClass, newSEL);
        }
        method_exchangeImplementations(originMethod, newMethod);
    }
}

+ (void)swizzlingWithOriginalSEL:(SEL)originalSEL
                          newSEL:(SEL)newSEL {
    [self swizzlingWithOriginalSEL:originalSEL
                            newSEL:newSEL
                        defaultSEL:nil
                   targetClassName:nil];
}


+ (void)swizzlingWithOriginalMedthName:(NSString *)originalMedthName
                          newMedthName:(NSString *)newMedthName
                      defaultMedthName:(NSString *)defaultMedthName
                       targetClassName:(NSString *)targetClassName {
    [self swizzlingWithOriginalSEL:NSSelectorFromString(originalMedthName)
                            newSEL:NSSelectorFromString(newMedthName)
                        defaultSEL:NSSelectorFromString(defaultMedthName)
                   targetClassName:targetClassName];
}

@end
